package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"goclient/src/conf"
	"goclient/src/rule"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"time"
)

// 配置文件路径（存储公钥的文件）
const AuthorizedKeysFile = "./authorized_keys" // 替换为实际的配置文件路径
var Config conf.Myconf
var Logger *log.Logger

// 主程序
func Start(ip string) {

	// var ip string
	// if len(os.Args) > 1 {
	// 	ip = os.Args[1]
	// } else {
	// 	// 获取到ip
	// 	fmt.Println("请求获取到外网ip url:", config.Ipapi)
	// 	ip = conf.GetIp(config.Ipapi)
	// }
	// fmt.Println("外网ip获取成功：", ip)

	ipFlag := conf.IsValidIP(ip)
	if !ipFlag {
		fmt.Println("ip地址不合法")
		return
	}

	// rule.YunMain()

	// 迭代
	for _, item := range Config.Devices {
		fmt.Printf("开始实例id: %s", item.Instanceid)
		if item.Type == 1 {
			rule.GetRules(item, ip)
		} else if item.Type == 2 {
			rule.YunMain(item, ip)
		} else if item.Type == 3 {
			rule.VpcRule(item, ip)
		}
	}
}


func main() {
	// 打开日志文件
	file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalf("Failed to open log file: %v", err)
	}
	defer file.Close()

	// 创建自定义日志记录器
	Logger = log.New(file, "CUSTOM: ", log.Ldate|log.Ltime|log.Lshortfile)
	Logger.Println("开始运行...")
	// 获取配置
	Config = conf.GetConfig()

	// 启动HTTP服务器
	http.HandleFunc("/api/check-rule", CheckRuleHandler)
	logStr := "服务启动成功 端口： " + fmt.Sprintf(":%d", Config.Port)
	Logger.Println(logStr)
	log.Println(logStr)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", Config.Port), nil))
}

// 处理公钥校验请求
func CheckRuleHandler(w http.ResponseWriter, r *http.Request) {
	// 读取请求体中的公钥
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Failed to read request body", http.StatusBadRequest)
		return
	}
	defer r.Body.Close()

	// 必须是 post 请求
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// 获取请求头中的用户名
	username := r.Header.Get("User")
	if username == "" {
		http.Error(w, "Username header is missing", http.StatusBadRequest)
		return
	}
	fmt.Println("username", username)

	pubKey := strings.TrimSpace(string(body))

	// 读取本地配置文件
	fileSrc := AuthorizedKeysFile + "/" + username + ".pub"
	fmt.Println("fileSrc", fileSrc)
	authorizedKeys, err := ioutil.ReadFile(fileSrc)
	if err != nil {
		http.Error(w, "Failed to read authorized_keys file", http.StatusInternalServerError)
		return
	}

	// fmt.Println("authorizedKeys", string(authorizedKeys));
	// fmt.Println("pubKey", pubKey)

	// 检查公钥是否存在于配置文件中
	if (GenerateSignature(strings.TrimSpace(string(authorizedKeys)),username) != pubKey) {
		fmt.Println("公钥匹配失败", time.Now().Format("2006-01-02 15:04:00"))
		fmt.Fprintln(w, "error")
		return 
	}
	logStr := "公钥匹配成功,用户：" + username + " 时间：" + time.Now().Format("2006-01-02 15:04:00")
	Logger.Println(logStr)
	log.Println(logStr)
	fmt.Println(logStr)
	fmt.Fprintln(w, "ok")
	// 获取到 当前客户端ip
	ip := r.RemoteAddr
	fmt.Println("ip", ip)
	if ip == "" {
		fmt.Println("ip为空")
		return
	}

	// 去除 ip的后面端口号
	ip = strings.Split(ip, ":")[0]
	logStr = "修改规则组 ip：" + ip + " 用户：" + username + " 时间：" + time.Now().Format("2006-01-02 15:04:00")
	Logger.Println(logStr)
	log.Println(logStr)
	fmt.Println(logStr)
	Start(ip)
	
	// Start()
}

// 生成签名（使用 SHA-256）
func GenerateSignature(data string,username string) string {
	// 创建 SHA-256 哈希对象
	hash := sha256.New()

	// 写入数据
	hash.Write([]byte(username + data + time.Now().Format("2006-01-02 15:04")))

	// 计算哈希值
	hashSum := hash.Sum(nil)

	// 将哈希值转换为十六进制字符串
	return hex.EncodeToString(hashSum)
}